package com.daxia.bumall.web.controller.m;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.daxia.bumall.common.AuditStatus;
import com.daxia.bumall.common.MyJSONObject;
import com.daxia.bumall.common.NeedLogin;
import com.daxia.bumall.common.SessionCache;
import com.daxia.bumall.common.Sex;
import com.daxia.bumall.common.UserType;
import com.daxia.bumall.dto.DesignDTO;
import com.daxia.bumall.dto.DesignerDTO;
import com.daxia.bumall.dto.OPResultDTO;
import com.daxia.bumall.dto.TimelineDTO;
import com.daxia.bumall.dto.UserDTO;
import com.daxia.bumall.dto.UserHeadImagesDTO;
import com.daxia.bumall.exception.BizException;
import com.daxia.bumall.model.Designer;
import com.daxia.bumall.model.User;
import com.daxia.bumall.support.Page;
import com.daxia.bumall.util.ImageUtils;
import com.daxia.bumall.util.UserHelper;
import com.daxia.bumall.util.ValidationUtils;

@Controller
@RequestMapping(value = "/m/user", produces = "application/json;charset=UTF-8")
public class MUserController extends MBaseController {
	
	private static final Logger logger = Logger.getLogger(MUserController.class);
	@Autowired
    private SessionCache sessionCache;
	
	@ResponseBody
	@RequestMapping("login")
	public String login(String mobile, String password, HttpServletRequest request) throws Exception {
		UserDTO user = userService.login(mobile, password);
		if (user == null) {
			throw new BizException("用户名或密码不正确");
		}
		
		if (StringUtils.isNotBlank(user.getHeadImage())) {
			user.setHeadImage(ImageUtils.getImageFullPath(request, user.getHeadImage()));
		}
		//更新最后登录时间
		userService.updateLastLoginTime(user.getId());
		userService.count(user);
		MyJSONObject data = buildUserJson(user);
		MyJSONObject designerInfo = new MyJSONObject();
		List<Designer> designers = user.getDesigners();
		if (CollectionUtils.isNotEmpty(designers)) {
			Designer designer = designers.get(0);
			designerInfo.put("auditStatus", designer.getAuditStatus());
			designerInfo.put("auditStatusRemark", AuditStatus.getByValue(designer.getAuditStatus()).getRemark());
			designerInfo.put("designerId", designer.getId());
			data.put("designerInfo", designerInfo);
		} 
		// return toApiOutput(user, UserAPIDTO.class, UserInfoAPIDTO.class);
		String sessionID = user.getSessionID();
		if (StringUtils.isBlank(sessionID)) {
			sessionID = UUID.randomUUID().toString().replace("-", "");
			sessionCache.set(user.getId(), sessionID);
		
			
			user.setSessionID(sessionID);
			
			userService.updateAllFields(user);
			
		}
        data.put("sessionId", sessionID);
		return toJson(data);
	}

	/**
	 * 如果userId不为空则表示 是绑定手机号
	 *
	 * @param mobile
	 * @param validateCode
	 * @param inviteCode
	 * @param password
	 * @param request
	 * @param client
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	@RequestMapping("register")
	public String register(String mobile, String validateCode, String inviteCode, String password,
			HttpServletRequest request, String client) throws Exception {
		super.assertNotBlank(mobile, "手机号码不能为空");
		ValidationUtils.validateMobile(mobile, "手机号码不合法");

		validateCode(mobile, validateCode);
		if (userService.isMobileRegistered(mobile)) {
			throw new BizException("该手机号码已经被注册了");
		}

		Long id = userService.registerForMobile(mobile, inviteCode, client, password);
		UserDTO user = userService.load(id);
		return toJson(buildUserJson(user));

	}

	/**
	 *  密码重置
	 *
	 * @param mobile 手机号, 也是帐号
	 * @param password	新密码
	 * @param confirmPassword 重复新密码
	 * @param validateCode 验证码
	 * @param client client 值
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	@RequestMapping("resetPassword")
	public String resetPassword(String mobile, String password, String confirmPassword, String validateCode, String client) throws Exception {
		super.assertNotBlank(mobile, "手机号码不能为空");
		ValidationUtils.validateMobile(mobile, "手机号码不合法");

		if ( StringUtils.isBlank(password) || StringUtils.isBlank(confirmPassword) ){
			throw new BizException("密码不能为空");
		}

		if ( !StringUtils.endsWithIgnoreCase(password, confirmPassword) ){
			throw new BizException("密码两次输入不一致");
		}

		validateCode(mobile, validateCode);

		OPResultDTO result = userService.resetPassword(mobile, password, client);

		return toJson(result);
	}

    /**
     * 我的粉丝
     *
     * @param mobile  用户手机号码
     * @param token   认证授权token
     * @param client  client值
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping("myFans")
    public String myFans(String mobile, String token, String client) throws Exception {
        super.assertNotBlank(mobile, "手机号码不能为空");
        ValidationUtils.validateMobile(mobile, "手机号码不合法");

        Page page = new Page();
        page.setPageSize(20);
        page.setPage(1);

        List<UserDTO> fans = userService.loadMyFans(mobile, client, page);

        JSONArray fanList = new JSONArray();
        for (UserDTO fan : fans) {
            MyJSONObject obj = new MyJSONObject();
            obj.put("username", fan.getUsername());
            obj.put("nickName", fan.getNickName());
            obj.put("headImage", ImageUtils.getImageFullPath(fan.getHeadImage()));
            obj.put("mobile", fan.getMobile());
            fanList.add(obj);
        }

        MyJSONObject json = new MyJSONObject();
        super.setPageInfo(json, page);
        json.put("fans", fanList);

        return toJson(json);
    }

    /**
     * 我的关注
     *
     * @param mobile  用户手机号码
     * @param token   认证授权token
     * @param client  client值
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping("myDesigners")
    public String myDesigners(String mobile, String token, String client) throws Exception {
        super.assertNotBlank(mobile, "手机号码不能为空");
        ValidationUtils.validateMobile(mobile, "手机号码不合法");

        Page page = new Page();
        page.setPageSize(20);
        page.setPage(1);

        List<UserDTO> designers = userService.loadMyDesigners(mobile, client, page);

        JSONArray fanList = new JSONArray();
        for (UserDTO designer : designers) {
            MyJSONObject obj = new MyJSONObject();
            obj.put("username", designer.getUsername());
            obj.put("nickName", designer.getNickName());
            obj.put("headImage", ImageUtils.getImageFullPath(designer.getHeadImage()));
            obj.put("mobile", designer.getMobile());
            fanList.add(obj);
        }

        MyJSONObject json = new MyJSONObject();
        super.setPageInfo(json, page);
        json.put("designers", fanList);

        return toJson(json);
    }


	private MyJSONObject buildUserJson(UserDTO user) {
		MyJSONObject json = new MyJSONObject();
		json.put("id", user.getId());
		json.put("username", user.getUsername());
		json.put("nickName", user.getNickName());
		json.put("headImage", ImageUtils.getImageFullPath(user.getHeadImage()));
		json.put("mobile", user.getMobile());
		json.put("userType", user.getType());
		json.put("userTypeRemark", UserType.getByValue(user.getType()).getRemark());

		/**
		 * 登陆api返回的用户信息增加下列字段
		 动态数，订单数，作品数（Design)，收藏数(DesignCollection)
		 */
		json.put("timelineNum", user.getTimelineNum());
		json.put("orderNum", user.getOrderNum());
		json.put("designNum", user.getDesignNum());
		json.put("designCollectionNum", user.getDesignCollectionNum());


		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		String birthday = null;
		if (user.getBirthday() != null) {
			birthday = dateFormat.format(user.getBirthday());
		}
		json.put("birthday", birthday);

		json.put("pushAlias", UserHelper.getPushAlias(user.getId()));
		json.put("pushTag", UserHelper.getPushTag(user.getId()));

		return json;
	}
	
	@NeedLogin
	@ResponseBody
	@RequestMapping("update")
	public String update(String id, UserDTO userDTO, DesignerDTO designerDTO, HttpServletRequest request) throws Exception {
		logger.info("user request is : " + userDTO.toString() + "designer request is : " + designerDTO.toString());
	
		String image = super.saveFilesAndReturnFileName(request);
		logger.info("image is " + image);
		if (StringUtils.isNotBlank(image)) {
			User user = getCurrentUser();
			UserHeadImagesDTO userHeadImagesDTO = new UserHeadImagesDTO();
			userHeadImagesDTO.setHeadImage(user.getHeadImage());
			userHeadImagesDTO.setCreateTime(new Date());
			userHeadImagesService.create(userHeadImagesDTO);
			
			userDTO.setHeadImage(image);
		}
    	UserDTO uDTO = getCurrentUserDTO();
    	DesignerDTO designerQuery = new DesignerDTO();
    	User userQuery = new User();
		userQuery.setId(uDTO.getId());
		designerQuery.setUser(userQuery);
		DesignerDTO dDTO = designerService.findOne(designerQuery);
		logger.info("uDTO" + uDTO);
		uDTO.setNickName(userDTO.getNickName());
		if (userDTO.getSex() != null) {
			uDTO.setSex(userDTO.getSex());
		}
		if (userDTO.getProvince() != null && userDTO.getProvince().getId() != null) {
			uDTO.setProvince(userDTO.getProvince());
		}
		if (userDTO.getCity() != null && userDTO.getCity().getId() != null) {
			uDTO.setCity(userDTO.getCity());
		}
		if (userDTO.getDistrict() != null && userDTO.getDistrict().getId() != null) {
			uDTO.setDistrict(userDTO.getDistrict());
		}
		if (StringUtils.isNotBlank(userDTO.getStateMessage())) {
			uDTO.setStateMessage(userDTO.getStateMessage());
		}
		if (StringUtils.isNotBlank(userDTO.getNickName())) {
			uDTO.setNickName(userDTO.getNickName());
		}
		if (StringUtils.isNotBlank(userDTO.getHeadImage())) {
			uDTO.setHeadImage(userDTO.getHeadImage());
		}
		
		userService.updateAllFields(uDTO);
		if (dDTO != null && designerDTO != null) {
			dDTO.setGoodAtStyles(designerDTO.getGoodAtStyles());
			dDTO.setServiceArea(designerDTO.getServiceArea());
			dDTO.setWorkAge(designerDTO.getWorkAge());
			designerService.updateAllFields(dDTO);
		}
		
		return toJson();
	}
	
	/**
	 * 修改密码
	 * @param password  原密码
	 * @param newPassword 新密码
	 * @param confirmPassword 新密码确认
	 * @return
	 * @throws Exception
	 */
	@NeedLogin
	@ResponseBody
	@RequestMapping("changePassword")
	public String changePassword(String password, String newPassword, String confirmPassword) throws Exception {
		UserDTO uDTO = getCurrentUserDTO();
		
		UserDTO userDTO = userService.load(uDTO.getId());
		String newPwd = passwordEncoder.encodePassword(confirmPassword, userDTO.getUsername());
		userDTO.setPassword(newPwd);
		userService.updateAllFields(userDTO);
		return toJson();
	}
	
	
	@ResponseBody
	@RequestMapping("detail")
	public String detail(Long userId) throws Exception { 
		notNull(userId, "userId can not be null");
		MyJSONObject data = new MyJSONObject();
		JSONArray userHeadImageInfos = new JSONArray();
		JSONArray timelineInfos = new JSONArray();
		
		UserDTO userDTO = userService.load(userId);
		User user = new User();
		BeanUtils.copyProperties(userDTO, user);
		
		UserHeadImagesDTO userHeadImageQuery = new UserHeadImagesDTO();
		userHeadImageQuery.setUser(user);
		Page userHeadPage = new Page();
		userHeadPage.setPageSize(8);
		userHeadPage.setPage(1);
		List<UserHeadImagesDTO> userImagesList = userHeadImagesService.find(userHeadImageQuery, userHeadPage);
		for (UserHeadImagesDTO headImageDTO : userImagesList) {
			userHeadImageInfos.add(headImageDTO.getHeadImage());
		}
		
		TimelineDTO timelineQuery = new TimelineDTO();
		timelineQuery.setUser(user);
		Page timelinePage = new Page();
		timelinePage.setPage(1);
		timelinePage.setPageSize(8);
		List<TimelineDTO> timelineList = timelineService.find(timelineQuery, timelinePage);
		for (TimelineDTO timelineDTO : timelineList) {
			JSONObject timelineInfo = new JSONObject();
			timelineInfo.put("id", timelineDTO.getId());
			String headImage = "";
			String images = timelineDTO.getImages();
			String[] imgs = images.split(",");
			if (imgs.length > 0) {
				headImage = imgs[0];
			}
			timelineInfo.put("headImage", headImage);
			timelineInfos.add(timelineInfo);
		}
		
		if (user.getType().intValue() == UserType.Designer.getValue()) {
			JSONObject designerInfo = new JSONObject();
			DesignerDTO designerQuery = new DesignerDTO();
			User userQuery = new User();
			userQuery.setId(user.getId());
			designerQuery.setUser(userQuery);
			DesignerDTO designerDTO = designerService.findOne(designerQuery);
			if (designerDTO != null) {
				designerInfo.put("company", designerDTO.getCompany());
				designerInfo.put("workAge", designerDTO.getWorkAge());
				designerInfo.put("serviceArea", designerDTO.getServiceArea());
				designerInfo.put("goodAtStyles", designerDTO.getGoodAtStyles());
				designerInfo.put("mobile", user.getMobile());
				designerInfo.put("career", "设计师");
			}
			data.put("designerInfo", designerInfo);
			
			DesignDTO designQuery = new DesignDTO();
			designQuery.setUser(userQuery);
			Page designPage = new Page();
			List<DesignDTO> designs = designService.find(designQuery, designPage);
			JSONArray designInfos = new JSONArray();
			for (DesignDTO designDTO : designs) {
				MyJSONObject designInfo = new MyJSONObject();
				designInfo.put("id", designDTO.getId());
				designInfo.put("headImage", designDTO.getHeadImage());
				designInfos.add(designInfo);
			}
			data.put("designInfos", designInfos);
		}
		
		data.put("userHeadImageInfos", userHeadImageInfos);
		data.put("username", user.getUsername());
		data.put("headImage", user.getHeadImage());
		data.put("realName", user.getRealName());
		data.put("nickName", user.getNickName());
		data.put("sex", user.getSex());
		data.put("sexRemark", Sex.getByValue(user.getSex()).getRemark());
		data.put("timelineInfos", timelineInfos);
		data.put("mobile", user.getMobile());
		data.put("communityName", user.getCommunityName());
		data.put("stateMessage", user.getStateMessage());
		
		String address = "";
		MyJSONObject provinceInfo = new MyJSONObject();
		if (user.getProvince() != null) {
			provinceInfo.put("id", user.getProvince().getId());
			provinceInfo.put("name", user.getProvince().getName());
			address +=  user.getProvince().getName();
		}
		MyJSONObject cityInfo = new MyJSONObject();
		if (user.getCity() != null) {
			cityInfo.put("id", user.getCity().getId());
			cityInfo.put("name", user.getCity().getName());
			address += " " + user.getCity().getName();
		}
		MyJSONObject districtInfo = new MyJSONObject();
		if (user.getDistrict() != null) {
			districtInfo.put("id", user.getDistrict().getId());
			districtInfo.put("name", user.getDistrict().getName());
			address += " " + user.getDistrict().getName();
		}
		
		data.put("address", address);
		data.put("provinceInfo", provinceInfo);
		data.put("cityInfo", cityInfo);
		data.put("districtInfo", districtInfo);
		return toJson(data);
	}
	
	@NeedLogin
	@ResponseBody
	@RequestMapping("userInfo")
	public String userInfo() throws Exception {
		UserDTO user = getCurrentUserDTO();
	
		userService.count(user);
		MyJSONObject data = buildUserJson(user);
		MyJSONObject designerInfo = new MyJSONObject();
		List<Designer> designers = user.getDesigners();
		if (CollectionUtils.isNotEmpty(designers)) {
			Designer designer = designers.get(0);
			designerInfo.put("auditStatus", designer.getAuditStatus());
			designerInfo.put("auditStatusRemark", AuditStatus.getByValue(designer.getAuditStatus()).getRemark());
			data.put("designerInfo", designerInfo);
		} 
		String sessionId = UUID.randomUUID().toString().replace("-", "");
        sessionCache.set(user.getId(), sessionId);
        data.put("sessionId", sessionCache.getSessionId(user.getId()));
        
        return toJson(data);
	}
	
	/**
	 * 上传客户经纬度信息
	 * @param latitude 纬度
	 * @param longitude 经度
	 * @return
	 * @throws Exception
	 */
	@NeedLogin
	@ResponseBody
	@RequestMapping("position")
	public String position(Double latitude, Double longitude) throws Exception {
		UserDTO user = getCurrentUserDTO();
		user.setLatitude(latitude);
		user.setLongitude(longitude);
		user.setLastGpsUpdatedTime(new Date());
		userService.updateAllFields(user);
		return toJson();
	}
}
